#ifndef CIOPS_OPERATIONMANAGER_H
#define CIOPS_OPERATIONMANAGER_H

#include <vector>
#include <stack>

#include "Operation.h"
#include "ActionOpCreation.h"
#include "../Core/Vector3D.h"

namespace CIView {
    class View;
}

namespace CIGui {
    class MainWindow;
}

namespace CIOps {
    class Operation;

    /**
     * This class represents the manger to create and handle all needed operations   
     **/
    class OperationManager {                
        //Friend classes
        friend class CIGui::MainWindow;
        friend class CIView::View;

    public:            
        OperationManager (std::vector<CIView::View*>& v);           //Constructor
        virtual ~OperationManager();                                //Destructor

        //Operations'id
        enum {
            CREATE_VERTEX           //Create-Vertex-Operation 
          , CREATE_TRIANGLE         //Create-Triangle-Operation 
          , CREATE_TRIANGLE_STRIP   //Create-Triangle-Strip-Operation 
          , CREATE_RECTANGLE        //Create-Rectangle-Operation 
          , CREATE_CUBOID           //Create-Cuboid-Operation 
          , CREATE_SPHERE           //Create-Sphere-Operation 
          , CREATE_CYLINDER         //Create-Cylinder-Operation 
          , CREATE_CONE             //Create-Cone-Operation 
          , CREATE_TORUS            //Create-Torus-Operation 

          , SELECT_GEOMETRIES       //Select-Geometries-Operation
          , SELECT_FACES            //Select-Faces-Operation
          , SELECT_VERTICES         //Select-Vertices-Operation

          , TRANSLATE               //Translate-Primitives-Operation
          , SCALE                   //Scale-Primitives-Operation
          , ROTATE                  //Rotate-Primitives-Operation
          , EXTRUDE                 //Extrude-Primitives-Operation

          , DELETE_SELECTION        //Delete-Primitives-Operation
          , DUPLICATE_SELECTION     //Duplicate-Primitives-Operation

          , SELECT_ALL              //Select-All-Operation
          , DESELECT_ALL            //Deselect-All-Operation
          , INVERT_SELECTION        //Invert-Selection-Operation

          , HIDE                    //Hide-Selection-Operation
          , UNHIDE                  //Unhide-All-Operation
        };       

    protected:
        std::vector<CIView::View*>& views;          //The 3D views

        //Variables to track all operations executed by the user
        Operation* todoOp;                  //A pointer that contains the operation to execute 
        std::stack<Operation*> undoOps;     //A stack that contains all operations executed by the user, that can be canceled
        std::stack<Operation*> redoOps;     //A stack that contains all operations canceled by the user, that can be performed again


    public:
        //Utility Methods
        Operation* CreateOperation (int opID);                   //Method called to create the operation identified by opID integer
        QAction* CreateAction (const QString& iconPath,          //Method called to create the action associated with the operation identified by opID
                               const QString& tooltip, 
                               const QString& shortcut, 
                               QObject* parent, 
                               int viewsStatus,
                               int opID=-1);  

        bool CheckOperationStatus();            //Method called to check the current operation status
        void DoOperation (int opID);            //Method called to create and execute the operation identified by opID integer
        void UndoOperation();                   //Method called to undo the last user operation 
        void RedoOperation();                   //Method called to redo the last user operation canceled 
        
        void DeleteUselessOps();                //Method called whenever a new operation has been created, to delete all operations became useless
        void Reset();                           //Method called to reset the manager
                            
        //Static variables, used to set the operations parameters from the user interface
        static CICore::Vector3D X_Y_Z_Params;
        static bool CenterOfMass;
        static bool Origin;
        static bool UserPoint;
        static int Stacks;
        static int Slices;
        static float Thickness;        
        static bool IgnoreBackfaces;

    };
}

#endif /* CIOPS_OPERATIONMANAGER_H */
